package com.ruoyi.common.datapermission.rule.impl;

import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryTable;
import com.ruoyi.common.core.core.domain.R;
import com.ruoyi.common.datapermission.config.AuthProperties;
import com.ruoyi.common.datapermission.rule.DataPermissionRule;
import com.ruoyi.common.security.utils.LoginHelper;
import com.ruoyi.system.api.permission.PermissionApi;
import com.ruoyi.system.api.permission.dto.DeptDataPermissionRespDTO;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;

public abstract class AbstractDataPermissionRuleImpl implements DataPermissionRule {
    @Lazy
    @Resource
    protected PermissionApi permissionApi;
    @Lazy
    @Resource
    protected AuthProperties authProperties;

    protected static final Map<String, QueryColumn> COLUMN_CACHE = new ConcurrentHashMap<>();

    /**
     * 获取查询列
     * @param queryTable
     * @param columnName
     * @return
     */
    protected QueryColumn getQueryColumn(QueryTable queryTable, String columnName) {
        String cacheKey = String.format("%s.%s.%s", queryTable.getSchema(), queryTable.getName(), columnName);
        QueryColumn column = COLUMN_CACHE.get(cacheKey);
        if (column != null) {
            return column;
        }
        Field field = ReflectionUtils.findField(queryTable.getClass(), "DEFAULT_COLUMNS");
        if (field == null) {
            return null;
        }
        QueryColumn[] defaultColumns = (QueryColumn[]) ReflectionUtils.getField(field, queryTable);
        column = Stream.of(defaultColumns).filter(queryColumn -> queryColumn.getName().equals(columnName)).findFirst().orElseGet(null);
        if (column != null) {
            COLUMN_CACHE.put(cacheKey, column);
        }
        return column;
    }

    /**
     * 获取用户的部门数据权限值
     * @return
     */
    protected DeptDataPermissionRespDTO getDeptDataPermissionRespDTO() {
        R<DeptDataPermissionRespDTO> deptDataPermissionR = permissionApi.getDeptDataPermission(LoginHelper.getUserId());
        return deptDataPermissionR.getCheckedData();
    }

    /**
     * 认证类型
     * @return
     */
    protected abstract String authType();
}
